// ----------> GENERATED FILE - DON'T TOUCH! <----------

// generator: ilarkesto.mda.legacy.generator.EntityGenerator










package scrum.server.project;

import java.util.*;
import ilarkesto.core.logging.Log;
import ilarkesto.persistence.ADatob;
import ilarkesto.persistence.AEntity;
import ilarkesto.persistence.AStructure;
import ilarkesto.auth.AUser;
import ilarkesto.persistence.EntityDoesNotExistException;
import ilarkesto.base.Str;

public abstract class GProjectGroup
            extends AEntity
            implements ilarkesto.auth.ViewProtected<scrum.server.admin.User>, ilarkesto.search.Searchable, java.lang.Comparable<ProjectGroup> {

    // --- AEntity ---

    public final scrum.server.project.ProjectGroupDao getDao() {
        return projectGroupDao;
    }

    protected void repairDeadDatob(ADatob datob) {
    }

    @Override
    public void storeProperties(Map properties) {
        super.storeProperties(properties);
        properties.put("projectId", this.projectId);
        properties.put("number", this.number);
        properties.put("label", this.label);
        properties.put("description", this.description);
        properties.put("testDescription", this.testDescription);
        properties.put("storiesAssociatesIds", this.storiesAssociatesIds);
        properties.put("groupMembersIds", this.groupMembersIds);
    }

    public int compareTo(ProjectGroup other) {
        return toString().toLowerCase().compareTo(other.toString().toLowerCase());
    }

    private static final ilarkesto.core.logging.Log LOG = ilarkesto.core.logging.Log.get(GProjectGroup.class);

    public static final String TYPE = "projectGroup";


    // -----------------------------------------------------------
    // - Searchable
    // -----------------------------------------------------------

    public boolean matchesKey(String key) {
        if (super.matchesKey(key)) return true;
        if (matchesKey(getLabel(), key)) return true;
        if (matchesKey(getDescription(), key)) return true;
        if (matchesKey(getTestDescription(), key)) return true;
        return false;
    }

    // -----------------------------------------------------------
    // - project
    // -----------------------------------------------------------

    private String projectId;
    private transient scrum.server.project.Project projectCache;

    private void updateProjectCache() {
        projectCache = this.projectId == null ? null : (scrum.server.project.Project)projectDao.getById(this.projectId);
    }

    public final String getProjectId() {
        return this.projectId;
    }

    public final scrum.server.project.Project getProject() {
        if (projectCache == null) updateProjectCache();
        return projectCache;
    }

    public final void setProject(scrum.server.project.Project project) {
        project = prepareProject(project);
        if (isProject(project)) return;
        this.projectId = project == null ? null : project.getId();
        projectCache = project;
        updateLastModified();
        fireModified("project="+project);
    }

    protected scrum.server.project.Project prepareProject(scrum.server.project.Project project) {
        return project;
    }

    protected void repairDeadProjectReference(String entityId) {
        if (this.projectId == null || entityId.equals(this.projectId)) {
            repairMissingMaster();
        }
    }

    public final boolean isProjectSet() {
        return this.projectId != null;
    }

    public final boolean isProject(scrum.server.project.Project project) {
        if (this.projectId == null && project == null) return true;
        return project != null && project.getId().equals(this.projectId);
    }

    protected final void updateProject(Object value) {
        setProject(value == null ? null : (scrum.server.project.Project)projectDao.getById((String)value));
    }

    // -----------------------------------------------------------
    // - number
    // -----------------------------------------------------------

    private int number;

    public final int getNumber() {
        return number;
    }

    public final void setNumber(int number) {
        number = prepareNumber(number);
        if (isNumber(number)) return;
        this.number = number;
        updateLastModified();
        fireModified("number="+number);
    }

    protected int prepareNumber(int number) {
        return number;
    }

    public final boolean isNumber(int number) {
        return this.number == number;
    }

    protected final void updateNumber(Object value) {
        setNumber((Integer)value);
    }

    // -----------------------------------------------------------
    // - label
    // -----------------------------------------------------------

    private java.lang.String label;

    public final java.lang.String getLabel() {
        return label;
    }

    public final void setLabel(java.lang.String label) {
        label = prepareLabel(label);
        if (isLabel(label)) return;
        this.label = label;
        updateLastModified();
        fireModified("label="+label);
    }

    protected java.lang.String prepareLabel(java.lang.String label) {
        // label = Str.removeUnreadableChars(label);
        return label;
    }

    public final boolean isLabelSet() {
        return this.label != null;
    }

    public final boolean isLabel(java.lang.String label) {
        if (this.label == null && label == null) return true;
        return this.label != null && this.label.equals(label);
    }

    protected final void updateLabel(Object value) {
        setLabel((java.lang.String)value);
    }

    // -----------------------------------------------------------
    // - description
    // -----------------------------------------------------------

    private java.lang.String description;

    public final java.lang.String getDescription() {
        return description;
    }

    public final void setDescription(java.lang.String description) {
        description = prepareDescription(description);
        if (isDescription(description)) return;
        this.description = description;
        updateLastModified();
        fireModified("description="+description);
    }

    protected java.lang.String prepareDescription(java.lang.String description) {
        // description = Str.removeUnreadableChars(description);
        return description;
    }

    public final boolean isDescriptionSet() {
        return this.description != null;
    }

    public final boolean isDescription(java.lang.String description) {
        if (this.description == null && description == null) return true;
        return this.description != null && this.description.equals(description);
    }

    protected final void updateDescription(Object value) {
        setDescription((java.lang.String)value);
    }

    // -----------------------------------------------------------
    // - testDescription
    // -----------------------------------------------------------

    private java.lang.String testDescription;

    public final java.lang.String getTestDescription() {
        return testDescription;
    }

    public final void setTestDescription(java.lang.String testDescription) {
        testDescription = prepareTestDescription(testDescription);
        if (isTestDescription(testDescription)) return;
        this.testDescription = testDescription;
        updateLastModified();
        fireModified("testDescription="+testDescription);
    }

    protected java.lang.String prepareTestDescription(java.lang.String testDescription) {
        // testDescription = Str.removeUnreadableChars(testDescription);
        return testDescription;
    }

    public final boolean isTestDescriptionSet() {
        return this.testDescription != null;
    }

    public final boolean isTestDescription(java.lang.String testDescription) {
        if (this.testDescription == null && testDescription == null) return true;
        return this.testDescription != null && this.testDescription.equals(testDescription);
    }

    protected final void updateTestDescription(Object value) {
        setTestDescription((java.lang.String)value);
    }

    // -----------------------------------------------------------
    // - storiesAssociates
    // -----------------------------------------------------------

    private java.util.Set<String> storiesAssociatesIds = new java.util.HashSet<String>();

    public final java.util.Set<scrum.server.project.Requirement> getStoriesAssociates() {
        return (java.util.Set) requirementDao.getByIdsAsSet(this.storiesAssociatesIds);
    }

    public final void setStoriesAssociates(Collection<scrum.server.project.Requirement> storiesAssociates) {
        storiesAssociates = prepareStoriesAssociates(storiesAssociates);
        if (storiesAssociates == null) storiesAssociates = Collections.emptyList();
        java.util.Set<String> ids = getIdsAsSet(storiesAssociates);
        if (this.storiesAssociatesIds.equals(ids)) return;
        this.storiesAssociatesIds = ids;
        updateLastModified();
        fireModified("storiesAssociates="+Str.format(storiesAssociates));
    }

    protected Collection<scrum.server.project.Requirement> prepareStoriesAssociates(Collection<scrum.server.project.Requirement> storiesAssociates) {
        return storiesAssociates;
    }

    protected void repairDeadStoriesAssociateReference(String entityId) {
        if (this.storiesAssociatesIds.remove(entityId)) fireModified("storiesAssociates-=" + entityId);
    }

    public final boolean containsStoriesAssociate(scrum.server.project.Requirement storiesAssociate) {
        if (storiesAssociate == null) return false;
        return this.storiesAssociatesIds.contains(storiesAssociate.getId());
    }

    public final int getStoriesAssociatesCount() {
        return this.storiesAssociatesIds.size();
    }

    public final boolean isStoriesAssociatesEmpty() {
        return this.storiesAssociatesIds.isEmpty();
    }

    public final boolean addStoriesAssociate(scrum.server.project.Requirement storiesAssociate) {
        if (storiesAssociate == null) throw new IllegalArgumentException("storiesAssociate == null");
        boolean added = this.storiesAssociatesIds.add(storiesAssociate.getId());
        if (added) updateLastModified();
        if (added) fireModified("storiesAssociates+=" + storiesAssociate);
        return added;
    }

    public final boolean addStoriesAssociates(Collection<scrum.server.project.Requirement> storiesAssociates) {
        if (storiesAssociates == null) throw new IllegalArgumentException("storiesAssociates == null");
        boolean added = false;
        for (scrum.server.project.Requirement storiesAssociate : storiesAssociates) {
            added = added | this.storiesAssociatesIds.add(storiesAssociate.getId());
        }
        return added;
    }

    public final boolean removeStoriesAssociate(scrum.server.project.Requirement storiesAssociate) {
        if (storiesAssociate == null) throw new IllegalArgumentException("storiesAssociate == null");
        if (this.storiesAssociatesIds == null) return false;
        boolean removed = this.storiesAssociatesIds.remove(storiesAssociate.getId());
        if (removed) updateLastModified();
        if (removed) fireModified("storiesAssociates-=" + storiesAssociate);
        return removed;
    }

    public final boolean removeStoriesAssociates(Collection<scrum.server.project.Requirement> storiesAssociates) {
        if (storiesAssociates == null) return false;
        if (storiesAssociates.isEmpty()) return false;
        boolean removed = false;
        for (scrum.server.project.Requirement _element: storiesAssociates) {
            removed = removed | removeStoriesAssociate(_element);
        }
        return removed;
    }

    public final boolean clearStoriesAssociates() {
        if (this.storiesAssociatesIds.isEmpty()) return false;
        this.storiesAssociatesIds.clear();
        updateLastModified();
        fireModified("storiesAssociates cleared");
        return true;
    }

    protected final void updateStoriesAssociates(Object value) {
        Collection<String> ids = (Collection<String>) value;
        setStoriesAssociates((java.util.Set) requirementDao.getByIdsAsSet(ids));
    }

    // -----------------------------------------------------------
    // - groupMembers
    // -----------------------------------------------------------

    private java.util.Set<String> groupMembersIds = new java.util.HashSet<String>();

    public final java.util.Set<scrum.server.admin.User> getGroupMembers() {
        return (java.util.Set) userDao.getByIdsAsSet(this.groupMembersIds);
    }

    public final void setGroupMembers(Collection<scrum.server.admin.User> groupMembers) {
        groupMembers = prepareGroupMembers(groupMembers);
        if (groupMembers == null) groupMembers = Collections.emptyList();
        java.util.Set<String> ids = getIdsAsSet(groupMembers);
        if (this.groupMembersIds.equals(ids)) return;
        this.groupMembersIds = ids;
        updateLastModified();
        fireModified("groupMembers="+Str.format(groupMembers));
    }

    protected Collection<scrum.server.admin.User> prepareGroupMembers(Collection<scrum.server.admin.User> groupMembers) {
        return groupMembers;
    }

    protected void repairDeadGroupMemberReference(String entityId) {
        if (this.groupMembersIds.remove(entityId)) fireModified("groupMembers-=" + entityId);
    }

    public final boolean containsGroupMember(scrum.server.admin.User groupMember) {
        if (groupMember == null) return false;
        return this.groupMembersIds.contains(groupMember.getId());
    }

    public final int getGroupMembersCount() {
        return this.groupMembersIds.size();
    }

    public final boolean isGroupMembersEmpty() {
        return this.groupMembersIds.isEmpty();
    }

    public final boolean addGroupMember(scrum.server.admin.User groupMember) {
        if (groupMember == null) throw new IllegalArgumentException("groupMember == null");
        boolean added = this.groupMembersIds.add(groupMember.getId());
        if (added) updateLastModified();
        if (added) fireModified("groupMembers+=" + groupMember);
        return added;
    }

    public final boolean addGroupMembers(Collection<scrum.server.admin.User> groupMembers) {
        if (groupMembers == null) throw new IllegalArgumentException("groupMembers == null");
        boolean added = false;
        for (scrum.server.admin.User groupMember : groupMembers) {
            added = added | this.groupMembersIds.add(groupMember.getId());
        }
        return added;
    }

    public final boolean removeGroupMember(scrum.server.admin.User groupMember) {
        if (groupMember == null) throw new IllegalArgumentException("groupMember == null");
        if (this.groupMembersIds == null) return false;
        boolean removed = this.groupMembersIds.remove(groupMember.getId());
        if (removed) updateLastModified();
        if (removed) fireModified("groupMembers-=" + groupMember);
        return removed;
    }

    public final boolean removeGroupMembers(Collection<scrum.server.admin.User> groupMembers) {
        if (groupMembers == null) return false;
        if (groupMembers.isEmpty()) return false;
        boolean removed = false;
        for (scrum.server.admin.User _element: groupMembers) {
            removed = removed | removeGroupMember(_element);
        }
        return removed;
    }

    public final boolean clearGroupMembers() {
        if (this.groupMembersIds.isEmpty()) return false;
        this.groupMembersIds.clear();
        updateLastModified();
        fireModified("groupMembers cleared");
        return true;
    }

    protected final void updateGroupMembers(Object value) {
        Collection<String> ids = (Collection<String>) value;
        setGroupMembers((java.util.Set) userDao.getByIdsAsSet(ids));
    }

    public void updateProperties(Map<?, ?> properties) {
        for (Map.Entry entry : properties.entrySet()) {
            String property = (String) entry.getKey();
            if (property.equals("id")) continue;
            Object value = entry.getValue();
            if (property.equals("projectId")) updateProject(value);
            if (property.equals("number")) updateNumber(value);
            if (property.equals("label")) updateLabel(value);
            if (property.equals("description")) updateDescription(value);
            if (property.equals("testDescription")) updateTestDescription(value);
            if (property.equals("storiesAssociatesIds")) updateStoriesAssociates(value);
            if (property.equals("groupMembersIds")) updateGroupMembers(value);
        }
    }

    protected void repairDeadReferences(String entityId) {
        super.repairDeadReferences(entityId);
        repairDeadProjectReference(entityId);
        if (this.storiesAssociatesIds == null) this.storiesAssociatesIds = new java.util.HashSet<String>();
        repairDeadStoriesAssociateReference(entityId);
        if (this.groupMembersIds == null) this.groupMembersIds = new java.util.HashSet<String>();
        repairDeadGroupMemberReference(entityId);
    }

    // --- ensure integrity ---

    public void ensureIntegrity() {
        super.ensureIntegrity();
        if (!isProjectSet()) {
            repairMissingMaster();
            return;
        }
        try {
            getProject();
        } catch (EntityDoesNotExistException ex) {
            LOG.info("Repairing dead project reference");
            repairDeadProjectReference(this.projectId);
        }
        if (this.storiesAssociatesIds == null) this.storiesAssociatesIds = new java.util.HashSet<String>();
        Set<String> storiesAssociates = new HashSet<String>(this.storiesAssociatesIds);
        for (String entityId : storiesAssociates) {
            try {
                requirementDao.getById(entityId);
            } catch (EntityDoesNotExistException ex) {
                LOG.info("Repairing dead storiesAssociate reference");
                repairDeadStoriesAssociateReference(entityId);
            }
        }
        if (this.groupMembersIds == null) this.groupMembersIds = new java.util.HashSet<String>();
        Set<String> groupMembers = new HashSet<String>(this.groupMembersIds);
        for (String entityId : groupMembers) {
            try {
                userDao.getById(entityId);
            } catch (EntityDoesNotExistException ex) {
                LOG.info("Repairing dead groupMember reference");
                repairDeadGroupMemberReference(entityId);
            }
        }
    }


    // -----------------------------------------------------------
    // - dependencies
    // -----------------------------------------------------------

    static scrum.server.project.ProjectDao projectDao;

    public static final void setProjectDao(scrum.server.project.ProjectDao projectDao) {
        GProjectGroup.projectDao = projectDao;
    }

    static scrum.server.project.RequirementDao requirementDao;

    public static final void setRequirementDao(scrum.server.project.RequirementDao requirementDao) {
        GProjectGroup.requirementDao = requirementDao;
    }

    static scrum.server.project.ProjectGroupDao projectGroupDao;

    public static final void setProjectGroupDao(scrum.server.project.ProjectGroupDao projectGroupDao) {
        GProjectGroup.projectGroupDao = projectGroupDao;
    }

}